package com.polytech.diploma.SQLGenerator.Oracle.Functions.AnalyticFunctions;

import java.util.List;
import java.util.Map;

import com.polytech.diploma.SQLGenerator.Oracle.Arguments.Argument;
import com.polytech.diploma.SQLGenerator.Oracle.Functions.Expression;
import com.polytech.diploma.SQLGenerator.Oracle.Functions.AnalyticFunctions.WindowClause.WindowClause;
import com.polytech.diploma.SQLGenerator.Oracle.Statements.OrderByClause.OrderByClause;

public class AnalyticFunction implements Expression{
	
	protected Argument function;
	protected List<Argument> partitionByClause;
	protected List<OrderByClause> orderByArgs;
	protected WindowClause windowingClause;
	
	public AnalyticFunction(Builder builder)
	{
		this.function = builder.function;
		this.partitionByClause = builder.partitionByClause;
		this.orderByArgs = builder.orderByArgs;
		this.windowingClause = builder.windowingClause;
	}
	
	public static class Builder
	{
		private Argument function;
		private List<Argument> partitionByClause;
		private List<OrderByClause> orderByArgs;
		private WindowClause windowingClause;
		
		public Builder setFunction(Argument function) {
			this.function = function;
			return this;
		}
		public Builder setPartitionByClause(List<Argument> partitionByClause) {
			this.partitionByClause = partitionByClause;
			return this;
		}
		public Builder setOrderByArgs(List<OrderByClause> orderByArgs) {
			this.orderByArgs = orderByArgs;
			return this;
		}
		public Builder setWindowingClause(WindowClause windowingClause) {
			this.windowingClause = windowingClause;
			return this;
		}
		public AnalyticFunction build()
		{
			return new AnalyticFunction(this);
		}
	}

	public Argument getFunction() {
		return function;
	}

	public List<Argument> getPartitionByClause() {
		return partitionByClause;
	}

	public List<OrderByClause> getOrderByArgs() {
		return orderByArgs;
	}

	public WindowClause getWindowingClause() {
		return windowingClause;
	}

	@Override
	public Map<String, List<String>> getTablesWithFields(
			Map<String, List<String>> fieldMap) {
		if(function != null)
			fieldMap = function.getTablesWithFields(fieldMap);
		
		if(partitionByClause != null)
			for(Argument arg : partitionByClause)
			{
				fieldMap = arg.getTablesWithFields(fieldMap);
			}
		
		if(orderByArgs != null)
			for(OrderByClause orderByClause : orderByArgs)
			{
				fieldMap = orderByClause.getTablesWithFields(fieldMap);
			}
		
		if(windowingClause != null)
			fieldMap = windowingClause.getTablesWithFields(fieldMap);
		
		return fieldMap;
	}
}
